// public/js/avatarPlayer.js

const AvatarPlayer = {
    // 数据
    data: {
        enabled: false,           // 是否启用数字人
        isPlaying: false,         // 是否正在播放
        isPaused: false,          // 是否暂停
        sessionId: null,          // 当前会话ID
        channel: null,            // 数字人通道信息
        videoElement: null,       // 视频元素
        playerReady: false,       // 播放器是否就绪
        currentText: '',          // 当前播报文本
        textQueue: [],            // 播报队列
        loadingError: false,      // 加载错误标志
        dialogSDK: null,          // 数字人SDK实例
    },

    // 初始化
    init() {
        console.log("[数字人] 初始化数字人播放器UI");
        
        // 创建数字人视频元素
        this._createVideoElement();
        
        // 添加可见性监听
        document.addEventListener('visibilitychange', () => {
            if (document.visibilityState === 'visible' && !this.data.sessionId && this.data.enabled) {
                console.log("[数字人] 页面变为可见且无会话，创建新会话");
                this._createNewSession();
            }
        });
        
        return this;
    },
    
    // 设置启用状态
    setEnabled(enabled) {
        if (this.data.enabled === enabled) return;
        
        console.log(`[数字人] ${enabled ? '启用' : '禁用'}数字人功能`);
        
        if (enabled) {
            const container = document.getElementById('avatarPlayerContainer');
            if (container) {
                container.style.display = 'block';
                container.classList.remove('error', 'playing');
                container.classList.add('loading');
            }
            
            this.data.enabled = enabled;
            this._setupSession()
                .catch(error => {
                    console.error("[数字人] 启用数字人失败:", error);
                    this._resetState();
                    const event = new CustomEvent('avatarError', {
                        detail: { 
                            message: '数字人服务不可用，请稍后重试',
                            shouldResetSwitch: true
                        }
                    });
                    document.dispatchEvent(event);
                });
        } else {
            // 先重置状态，确保资源被正确释放
            this._resetState();
            
            // 延迟一小段时间后再关闭视频容器，确保状态已完全重置
            setTimeout(() => {
                const container = document.getElementById('avatarPlayerContainer');
                if (container) {
                    container.style.display = 'none';
                }
            }, 100);
        }
    },
    
    // 播报文本
    speak(text) {
        if (!this.data.enabled || !text.trim()) return Promise.resolve();
        
        if (!this.data.dialogSDK || !this.data.sessionId) {
            console.log("[数字人] 会话无效，重新创建会话");
            return this._setupSession().then(() => this._addToTextQueue(text));
        }
        
        return this._addToTextQueue(text);
    },
    
    // 暂停播报
    pause() {
        if (!this.data.isPlaying || !this.data.sessionId) return Promise.resolve();
        
        console.log("[数字人] 暂停播报");
        this.data.isPaused = true;
        
        if (this.data.dialogSDK) {
            this.data.dialogSDK.stopRecording();
        }
    },
    
    // 恢复播报
    resume() {
        if (!this.data.isPaused || !this.data.sessionId) return;
        
        console.log("[数字人] 恢复播报");
        this.data.isPaused = false;
        
        if (this.data.dialogSDK) {
            this.data.dialogSDK.startRecording()
                .then(() => {
                    console.log("[数字人] 录音已恢复");
                    this._processTextQueue();
                })
                .catch(error => {
                    console.error("[数字人] 恢复录音失败:", error);
                });
        }
    },
    
    // 停止播报
    stop() {
        if (!this.data.sessionId) return Promise.resolve();
        
        console.log("[数字人] 停止播报");
        this.data.textQueue = [];
        
        if (this.data.dialogSDK) {
            this.data.dialogSDK.stopRecording();
        }
        
        this.data.isPlaying = false;
        this.data.isPaused = false;
        this.data.currentText = '';
    },
    
    // 关闭数字人
    close() {
        console.log("[数字人] 关闭数字人");
        
        // 先停止播放
        this.stop();
        
        // 如果有SDK实例，先销毁
        if (this.data.dialogSDK) {
            try {
                // 先停止录音
                this.data.dialogSDK.stopRecording();
                
                // 断开连接
                if (this.data.dialogSDK.disconnect) {
                    this.data.dialogSDK.disconnect();
                }

                // 销毁实例
                if (typeof this.data.dialogSDK.destroy === 'function') {
                    this.data.dialogSDK.destroy();
                    console.log("[数字人] SDK实例已销毁");
                }
                
                this.data.dialogSDK = null;
            } catch (error) {
                console.error("[数字人] 断开SDK连接时出错:", error);
                // 即使出错也要尝试销毁
                try {
                    if (typeof this.data.dialogSDK.destroy === 'function') {
                        this.data.dialogSDK.destroy();
                    }
                } catch (e) {
                    console.error("[数字人] 销毁SDK实例时出错:", e);
                }
                this.data.dialogSDK = null;
            }
        }
        
        // 如果有会话ID，则关闭会话
        if (this.data.sessionId) {
            this._closeSession()
                .finally(() => {
                    // 重置状态
                    this.data.enabled = false;
                    this.data.sessionId = null;
                    this.data.channel = null;
                    this.data.playerReady = false;
                });
        } else {
            // 即使没有会话ID，也要重置状态
            this.data.enabled = false;
            this.data.channel = null;
            this.data.playerReady = false;
        }
        
        // 清理视频元素
        if (this.data.videoElement) {
            this.data.videoElement.srcObject = null;
            this.data.videoElement.load();
        }
    },
    
    // 内部方法: 创建数字人视频元素
    _createVideoElement() {
        const existingPlayer = document.getElementById('avatarPlayer');
        if (existingPlayer) {
            this.data.videoElement = existingPlayer;
            return;
        }
        
        const container = document.createElement('div');
        container.id = 'avatarPlayerContainer';
        container.className = 'avatar-player-container';
        
        const video = document.createElement('video');
        video.id = 'avatarPlayer';
        video.className = 'avatar-player';
        video.playsInline = true;
        video.autoplay = true;
        video.muted = false;
        
        const loader = document.createElement('div');
        loader.className = 'avatar-player-loader';
        loader.innerHTML = '<div class="spinner"></div><div class="loading-text">数字人加载中...</div>';
        
        const closeBtn = document.createElement('button');
        closeBtn.className = 'avatar-close-btn';
        closeBtn.innerHTML = '<i class="bi bi-x"></i>';
        closeBtn.title = '关闭数字人';
        closeBtn.addEventListener('click', () => {
            this.close();
            const container = document.getElementById('avatarPlayerContainer');
            if (container) {
                container.style.display = 'none';
            }
        });
        
        container.appendChild(video);
        container.appendChild(loader);
        container.appendChild(closeBtn);
        document.body.appendChild(container);
        
        this.data.videoElement = video;
    },
    
    // 内部方法: 设置数字人会话
    _setupSession() {
        if (this.data.sessionId) {
            return this._checkSessionStatus()
                .then(valid => {
                    if (!valid) {
                        return this._createNewSession();
                    }
                    return Promise.resolve();
                });
        }
        
        return this._createNewSession();
    },
    
    // 内部方法: 创建新会话
    _createNewSession() {
        console.log("[数字人] 创建新会话");
        
        if (this.data.sessionId) {
            this._closeSession();
        }
        
        const container = document.getElementById('avatarPlayerContainer');
        if (container) {
            container.style.display = 'block';
            container.classList.remove('error', 'playing');
            container.classList.add('loading');
        }
        
        return fetch('/api/avatar/session', {
            method: 'POST'
        })
        .then(response => {
            if (!response.ok) {
                const error = new Error('创建数字人会话失败: ' + response.statusText);
                error.status = response.status;
                throw error;
            }
            return response.json();
        })
        .then(data => {
            console.log("[数字人] 会话创建响应:", data);
            
            if (!data || !data.sessionId || !data.channel) {
                throw new Error('数字人会话创建失败: 服务器返回数据无效');
            }

            // 验证必要的参数
            const requiredChannelParams = ['channelId', 'token', 'userId'];
            const missingParams = requiredChannelParams.filter(param => !data.channel[param]);
            
            if (missingParams.length > 0) {
                throw new Error(`数字人会话创建失败: 缺少必要参数 ${missingParams.join(', ')}`);
            }
            
            // 保存会话信息
            this.data.sessionId = data.sessionId;
            this.data.channel = data.channel;
            
            // 初始化SDK
            const initParams = {
                tenantId: '3dtvj85575', // 使用固定的appId作为tenantId
                appId: '3dtvj85575',    // 使用固定的appId
                sessionId: data.sessionId,
                token: data.channel.token,
                channel: {
                    ...data.channel,
                    appId: '3dtvj85575'  // 确保channel中也使用相同的appId
                }
            };

            console.log("[数字人] SDK初始化参数:", initParams);
            
            return this._initDialogSDK(initParams);
        })
        .catch(error => {
            console.error("[数字人] 创建会话失败:", error);
            this._handleError(error);
            return Promise.reject(error);
        });
    },
    
    // 内部方法: 初始化数字人SDK
    _initDialogSDK(sessionData) {
        if (!window.DialogAvatarSDK) {
            return Promise.reject(new Error('数字人SDK未加载'));
        }
        
        const container = document.getElementById('avatarPlayerContainer');
        if (container) {
            container.style.display = 'block';
            container.classList.add('loading');
        }
        
        // 转换channel参数为小驼峰格式
        const channel = {
            appId: '3dtvj85575',  // 使用固定的appId
            channelId: sessionData.channel.channelId,
            expiredTime: sessionData.channel.expiredTime,
            gslb: sessionData.channel.gslb,
            nonce: sessionData.channel.nonce,
            token: sessionData.channel.token,
            type: sessionData.channel.type,
            userId: sessionData.channel.userId
        };
        
        this.data.dialogSDK = new window.DialogAvatarSDK({
            tenantId: '3dtvj85575',  // 使用固定的appId作为tenantId
            appId: '3dtvj85575',     // 使用固定的appId
            sessionId: sessionData.sessionId,
            token: sessionData.token,
            channel: channel,
            videoDOM: this.data.videoElement,
            options: {
                wsUrl: "wss://avatar-im.console.aliyun.com/ws",
                maxReconnectTimeout: 300000,
                audio: {
                    autoStartRecord: false,
                    interval: 100,
                    autoDodge: false
                },
                rtc: {
                    muted: false
                }
            },
            onInitSuccess: () => {
                console.log("[数字人] IM连接成功，RTC拉流成功");
                this.data.playerReady = true;
                this.data.loadingError = false;
                
                if (container) {
                    container.classList.remove('loading');
                    container.classList.add('playing');
                }
                
                // 开始录音
                this.data.dialogSDK.startRecording()
                    .then(() => {
                        console.log("[数字人] 录音启动成功");
                        this._processTextQueue();
                    })
                    .catch(error => {
                        console.error("[数字人] 录音启动失败:", error);
                    });
            },
            onError: (error) => {
                console.error("[数字人] SDK错误:", error);
                this._handleError(error);
            },
            onWarning: (msg) => {
                console.warn("[数字人] SDK警告:", msg);
            },
            onRecordingStart: () => {
                console.log("[数字人] 开始录音");
            },
            onRecordingStop: () => {
                console.log("[数字人] 停止录音");
            },
            onASR: (text, sentenceId) => {
                console.log(`[数字人] ASR识别文本: ${text}, ID: ${sentenceId}`);
            },
            onAnswer: (text, sentenceId) => {
                console.log(`[数字人] 回答文本: ${text}, ID: ${sentenceId}`);
            }
        });
        
        return this.data.dialogSDK.init()
            .catch(error => {
                console.error("[数字人] SDK初始化失败:", error);
                this._handleError(error);
                return Promise.reject(error);
            });
    },
    
    // 内部方法: 处理错误
    _handleError(error) {
        console.error("[数字人] 处理错误:", error);
        
        const container = document.getElementById('avatarPlayerContainer');
        if (container) {
            container.style.display = 'block';
            container.classList.add('error');
            container.classList.remove('loading', 'playing');
            
            let retryBtn = container.querySelector('.retry-button');
            if (!retryBtn) {
                retryBtn = document.createElement('button');
                retryBtn.className = 'retry-button';
                retryBtn.textContent = '重试';
                retryBtn.onclick = () => {
                    container.style.display = 'none';
                    this._createNewSession();
                };
                container.appendChild(retryBtn);
            }
        }
        
        // 如果是SDK错误，重置状态
        const errorMessage = error && (error.message || error.errorMsg);
        const isSDKError = error && (
            (typeof errorMessage === 'string' && errorMessage.includes('SDK')) ||
            error.source === 'Avatar' ||
            error.errorCode
        );
        
        if (isSDKError) {
            this._resetState();
        }
        
        // 根据错误类型设置错误消息
        let displayMessage = '数字人服务暂时不可用';
        if (error) {
            if (error.status === 500) {
                displayMessage = '数字人服务出现内部错误，请稍后重试';
            } else if (error.source === 'Avatar') {
                displayMessage = `数字人服务异常(${error.errorCode})：${error.errorMsg}`;
            } else if (errorMessage && errorMessage.includes('SDK')) {
                displayMessage = '数字人SDK初始化失败，请刷新页面重试';
            }
        }
        
        // 触发错误事件，传递错误信息
        const event = new CustomEvent('avatarError', {
            detail: { 
                message: displayMessage,
                shouldResetSwitch: true
            }
        });
        document.dispatchEvent(event);
    },
    
    // 内部方法: 重置状态
    _resetState() {
        // 先停止所有活动
        if (this.data.dialogSDK) {
            try {
                // 1. 先停止录音
                this.data.dialogSDK.stopRecording();
                
                // 2. 断开WebSocket连接
                if (typeof this.data.dialogSDK.disconnect === 'function') {
                    this.data.dialogSDK.disconnect();
                }

                // 3. 销毁SDK实例
                if (typeof this.data.dialogSDK.destroy === 'function') {
                    this.data.dialogSDK.destroy();
                    console.log("[数字人] SDK实例已销毁");
                }

                this.data.dialogSDK = null;
            } catch (error) {
                console.error("[数字人] 销毁SDK实例时出错:", error);
                // 即使出错也要尝试销毁
                try {
                    if (typeof this.data.dialogSDK.destroy === 'function') {
                        this.data.dialogSDK.destroy();
                    }
                } catch (e) {
                    console.error("[数字人] 销毁SDK实例时出错:", e);
                }
                this.data.dialogSDK = null;
            }
        }

        // 重置所有状态标志
        this.data.isPlaying = false;
        this.data.isPaused = false;
        this.data.playerReady = false;
        this.data.loadingError = false;
        this.data.textQueue = [];
        this.data.sessionId = null;
        this.data.channel = null;

        // 清理视频元素
        if (this.data.videoElement) {
            this.data.videoElement.srcObject = null;
            this.data.videoElement.load();
        }

        // 更新视频容器状态
        const container = document.getElementById('avatarPlayerContainer');
        if (container) {
            container.classList.remove('playing', 'loading');
            if (!this.data.enabled) {
                container.classList.add('error');
            }
        }

        // 触发状态变更事件
        const event = new CustomEvent('avatarStateChange', {
            detail: { enabled: this.data.enabled }
        });
        document.dispatchEvent(event);
    },
    
    // 内部方法: 关闭会话
    _closeSession() {
        if (!this.data.sessionId) return Promise.resolve();
        
        const sessionId = this.data.sessionId;
        this.data.sessionId = null;
        this.data.channel = null;
        
        return fetch(`/api/avatar/session/${sessionId}/close`, {
            method: 'POST'
        })
        .then(response => {
            if (response.ok) {
                console.log("[数字人] 会话已关闭");
            } else {
                console.warn("[数字人] 关闭会话失败，服务器响应异常");
                throw new Error('服务器响应异常');
            }
        })
        .catch(error => {
            console.error("[数字人] 关闭会话出错:", error);
            throw error;
        });
    },
    
    // 内部方法: 添加到文本队列
    _addToTextQueue(text) {
        if (!text.trim()) return Promise.resolve();
        
        console.log("[数字人] 添加文本到队列:", text);
        
        if (this.data.dialogSDK && this.data.playerReady) {
            return this.data.dialogSDK.sendText(text)
                .catch(error => {
                    console.error("[数字人] 发送文本失败:", error);
                    return Promise.reject(error);
                });
        } else {
            this.data.textQueue.push(text);
            return Promise.resolve();
        }
    },
    
    // 内部方法: 处理文本队列
    _processTextQueue() {
        if (this.data.isPaused || !this.data.dialogSDK || !this.data.playerReady) {
            return;
        }
        
        while (this.data.textQueue.length > 0) {
            const text = this.data.textQueue.shift();
            this.data.dialogSDK.sendText(text)
                .catch(error => {
                    console.error("[数字人] 处理队列文本失败:", error);
                });
        }
    },
    
    // 内部方法: 检查会话状态
    _checkSessionStatus() {
        if (!this.data.sessionId) return Promise.resolve(false);
        
        return fetch(`/api/avatar/session/${this.data.sessionId}`)
            .then(response => {
                if (!response.ok) return false;
                return response.json();
            })
            .then(data => {
                return data.status === 'active';
            })
            .catch(() => {
                return false;
            });
    },
    
    // 内部方法: 检查并重新连接
    _checkAndReconnect() {
        if (!this.data.enabled) return Promise.resolve();
        
        console.log("[数字人] 检查连接状态");
        
        return this._checkSessionStatus()
            .then(valid => {
                if (!valid) {
                    console.log("[数字人] 会话无效，尝试重新创建");
                    return this._createNewSession();
                }
            })
            .catch(() => {
                return this._createNewSession();
            });
    }
};

// 导出到全局
window.AvatarPlayer = AvatarPlayer;